home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-9.10-netbook-remix-PL.iso / casper / filesystem.squashfs / usr / share / pyshared / lsb_release.py < prev    next >
Text File  |  2009-09-10  |  10KB  |  289 lines

  1. #!/usr/bin/python
  2.  
  3. # LSB release detection module for Debian
  4. # (C) 2005-09 Chris Lawrence <lawrencc@debian.org>
  5.  
  6. #    This package is free software; you can redistribute it and/or modify
  7. #    it under the terms of the GNU General Public License as published by
  8. #    the Free Software Foundation; version 2 dated June, 1991.
  9.  
  10. #    This package is distributed in the hope that it will be useful,
  11. #    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. #    GNU General Public License for more details.
  14.  
  15. #    You should have received a copy of the GNU General Public License
  16. #    along with this package; if not, write to the Free Software
  17. #    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  18. #    02111-1307, USA.
  19.  
  20. import sys
  21. import commands
  22. import os
  23. import re
  24.  
  25. # XXX: Update as needed
  26. # This should really be included in apt-cache policy output... it is already
  27. # in the Release file...
  28. RELEASE_CODENAME_LOOKUP = {
  29.     '1.1' : 'buzz',
  30.     '1.2' : 'rex',
  31.     '1.3' : 'bo',
  32.     '2.0' : 'hamm',
  33.     '2.1' : 'slink',
  34.     '2.2' : 'potato',
  35.     '3.0' : 'woody',
  36.     '3.1' : 'sarge',
  37.     '4.0' : 'etch',
  38.     '5.0' : 'lenny',
  39.     }
  40.  
  41. TESTING_CODENAME = 'unknown.new.testing'
  42.  
  43. def lookup_codename(release, unknown=None):
  44.     m = re.match(r'(\d+)\.(\d+)(r(\d+))?', release)
  45.     if not m:
  46.         return unknown
  47.  
  48.     shortrelease = '%s.%s' % m.group(1,2)
  49.     return RELEASE_CODENAME_LOOKUP.get(shortrelease, unknown)
  50.  
  51. # LSB compliance packages... may grow eventually
  52. PACKAGES = 'lsb-core lsb-cxx lsb-graphics lsb-desktop lsb-qt4 lsb-languages lsb-multimedia lsb-printing'
  53.  
  54. modnamere = re.compile(r'lsb-(?P<module>[a-z0-9]+)-(?P<arch>[^ ]+)(?: \(= (?P<version>[0-9.]+)\))?')
  55.  
  56. def valid_lsb_versions(version, module):
  57.     # If a module is ever released that only appears in >= version, deal
  58.     # with that here
  59.     if version == '3.0':
  60.         return ['2.0', '3.0']
  61.     elif version == '3.1':
  62.         if module in ('desktop', 'qt4'):
  63.             return ['3.1']
  64.         else:
  65.             return ['2.0', '3.0', '3.1']
  66.     elif version == '3.2':
  67.         if module == 'desktop':
  68.             return ['3.1', '3.2']
  69.         elif module == 'qt4':
  70.             return ['3.1']
  71.         elif module in ('printing', 'languages', 'multimedia'):
  72.             return ['3.2']
  73.         elif module == 'cxx':
  74.             return ['3.0', '3.1', '3.2']
  75.         else:
  76.             return ['2.0', '3.0', '3.1', '3.2']
  77.     elif version == '4.0':
  78.         if module == 'desktop':
  79.             return ['3.1', '3.2', '4.0']
  80.         elif module == 'qt4':
  81.             return ['3.1']
  82.         elif module in ('printing', 'languages', 'multimedia'):
  83.             return ['3.2', '4.0']
  84.         elif module == 'security':
  85.             return ['4.0']
  86.         elif module == 'cxx':
  87.             return ['3.0', '3.1', '3.2', '4.0']
  88.         else:
  89.             return ['2.0', '3.0', '3.1', '3.2', '4.0']
  90.  
  91.     return [version]
  92.  
  93. try:
  94.     set # introduced in 2.4
  95. except NameError:
  96.     import sets
  97.     set = sets.Set
  98.  
  99. # This is Debian-specific at present
  100. def check_modules_installed():
  101.     # Find which LSB modules are installed on this system
  102.     output = commands.getoutput("dpkg-query -f '${Version} ${Provides}\n' -W %s 2>/dev/null" % PACKAGES)
  103.     if not output:
  104.         return []
  105.  
  106.     modules = set()
  107.     for line in output.split(os.linesep):
  108.         version, provides = line.split(' ', 1)
  109.         version = version.split('-', 1)[0]
  110.         for pkg in provides.split(','):
  111.             mob = modnamere.search(pkg)
  112.             if not mob:
  113.                 continue
  114.  
  115.             mgroups = mob.groupdict()
  116.             # If no versioned provides...
  117.             if mgroups.get('version'):
  118.                 module = '%(module)s-%(version)s-%(arch)s' % mgroups
  119.                 modules.add(module)
  120.             else:
  121.                 module = mgroups['module']
  122.                 for v in valid_lsb_versions(version, module):
  123.                     mgroups['version'] = v
  124.                     module = '%(module)s-%(version)s-%(arch)s' % mgroups
  125.                     modules.add(module)
  126.  
  127.     modules = list(modules)
  128.     modules.sort()
  129.     return modules
  130.  
  131. longnames = {'v' : 'version', 'o': 'origin', 'a': 'suite',
  132.              'c' : 'component', 'l': 'label'}
  133.  
  134. def parse_policy_line(data):
  135.     retval = {}
  136.     bits = data.split(',')
  137.     for bit in bits:
  138.         kv = bit.split('=', 1)
  139.         if len(kv) > 1:
  140.             k, v = kv[:2]
  141.             if k in longnames:
  142.                 retval[longnames[k]] = v
  143.     return retval
  144.  
  145. def parse_apt_policy():
  146.     data = []
  147.     
  148.     policy = commands.getoutput('LANG=C apt-cache policy 2>/dev/null')
  149.     for line in policy.split('\n'):
  150.         line = line.strip()
  151.         m = re.match(r'(\d+)', line)
  152.         if m:
  153.             priority = int(m.group(1))
  154.         if line.startswith('release'):
  155.             bits = line.split(' ', 1)
  156.             if len(bits) > 1:
  157.                 data.append( (priority, parse_policy_line(bits[1])) )
  158.  
  159.     return data
  160.  
  161. def guess_release_from_apt(origin='Debian', component='main',
  162.                            ignoresuites=('experimental'),
  163.                            label='Debian'):
  164.     releases = parse_apt_policy()
  165.  
  166.     if not releases:
  167.         return None
  168.  
  169.     # We only care about the specified origin, component, and label
  170.     releases = [x for x in releases if (
  171.         x[1].get('origin', '') == origin and
  172.         x[1].get('component', '') == component and
  173.         x[1].get('label', '') == label)]
  174.  
  175.     # Check again to make sure we didn't wipe out all of the releases
  176.     if not releases:
  177.         return None
  178.     
  179.     releases.sort()
  180.     releases.reverse()
  181.  
  182.     # We've sorted the list by descending priority, so the first entry should
  183.     # be the "main" release in use on the system
  184.  
  185.     return releases[0][1]
  186.  
  187. def guess_debian_release():
  188.     distinfo = {'ID' : 'Debian'}
  189.  
  190.     kern = os.uname()[0]
  191.     if kern in ('Linux', 'Hurd', 'NetBSD'):
  192.         distinfo['OS'] = 'GNU/'+kern
  193.     elif kern == 'FreeBSD':
  194.         distinfo['OS'] = 'GNU/k'+kern
  195.     else:
  196.         distinfo['OS'] = 'GNU'
  197.  
  198.     distinfo['DESCRIPTION'] = '%(ID)s %(OS)s' % distinfo
  199.  
  200.     if os.path.exists('/etc/debian_version'):
  201.         try:
  202.             release = open('/etc/debian_version').read().strip()
  203.         except IOError, msg:
  204.             print >> sys.stderr, 'Unable to open /etc/debian_version:', str(msg)
  205.             release = 'unknown'
  206.             
  207.         if not release[0:1].isalpha():
  208.             # /etc/debian_version should be numeric
  209.             codename = lookup_codename(release, 'n/a')
  210.             distinfo.update({ 'RELEASE' : release, 'CODENAME' : codename })
  211.         elif release.endswith('/sid'):
  212.             if release.rstrip('/sid').lower().isalpha() != 'testing':
  213.                 global TESTING_CODENAME
  214.                 TESTING_CODENAME = release.rstrip('/sid')
  215.             distinfo['RELEASE'] = 'testing/unstable'
  216.         else:
  217.             distinfo['RELEASE'] = release
  218.  
  219.     # Only use apt information if we did not get the proper information
  220.     # from /etc/debian_version or if we don't have a codename
  221.     # (which will happen if /etc/debian_version does not contain a
  222.     # number but some text like 'testing/unstable' or 'lenny/sid')
  223.     #
  224.     # This is slightly faster and less error prone in case the user
  225.     # has an entry in his /etc/apt/sources.list but has not actually
  226.     # upgraded the system.
  227.     rinfo = guess_release_from_apt()
  228.     if rinfo and not distinfo.get('CODENAME'):
  229.         release = rinfo.get('version')
  230.         if release:
  231.             codename = lookup_codename(release, 'n/a')
  232.         else:
  233.             release = rinfo.get('suite', 'unstable')
  234.             if release == 'testing':
  235.                 # Would be nice if I didn't have to hardcode this.
  236.                 codename = TESTING_CODENAME
  237.             else:
  238.                 codename = 'sid'
  239.         distinfo.update({ 'RELEASE' : release, 'CODENAME' : codename })
  240.  
  241.     if distinfo.get('RELEASE'):
  242.         distinfo['DESCRIPTION'] += ' %(RELEASE)s' % distinfo
  243.     if distinfo.get('CODENAME'):
  244.         distinfo['DESCRIPTION'] += ' (%(CODENAME)s)' % distinfo
  245.  
  246.     return distinfo
  247.  
  248. # Whatever is guessed above can be overridden in /etc/lsb-release
  249. def get_lsb_information():
  250.     distinfo = {}
  251.     if os.path.exists('/etc/lsb-release'):
  252.         try:
  253.             for line in open('/etc/lsb-release'):
  254.                 line = line.strip()
  255.                 if not line:
  256.                     continue
  257.                 # Skip invalid lines
  258.                 if not '=' in line:
  259.                     continue
  260.                 var, arg = line.split('=', 1)
  261.                 if var.startswith('DISTRIB_'):
  262.                     var = var[8:]
  263.                     if arg.startswith('"') and arg.endswith('"'):
  264.                         arg = arg[1:-1]
  265.                     if arg: # Ignore empty arguments
  266.                         distinfo[var] = arg
  267.         except IOError, msg:
  268.             print >> sys.stderr, 'Unable to open /etc/lsb-release:', str(msg)
  269.             
  270.     return distinfo
  271.  
  272. def get_distro_information():
  273.     lsbinfo = get_lsb_information()
  274.     # OS is only used inside guess_debian_release anyway
  275.     for key in ('ID', 'RELEASE', 'CODENAME', 'DESCRIPTION',):
  276.         if key not in lsbinfo:
  277.             distinfo = guess_debian_release()
  278.             distinfo.update(lsbinfo)
  279.             return distinfo
  280.     else:
  281.         return lsbinfo
  282.  
  283. def test():
  284.     print get_distro_information()
  285.     print check_modules_installed()
  286.  
  287. if __name__ == '__main__':
  288.     test()
  289.